<<<<<<< HEAD ======= >>>>>>> ad0bc60fadc363530d65adc66a558bb30ba913a4

Welcome to our Recommendations Page!

Looking for a new romance book? Want to get into some classics? Looking to read another book by your favorite author? Fear not! You can find book recommendations right here. Search by your favorite author or genre and your preferred rating.

Have fun reading!

<<<<<<< HEAD
library(tidyverse)
library(shiny)
library(bslib)
library(dplyr)
=======
library(tidyverse)
## ── Attaching core tidyverse packages ─────────────────
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ──────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(shiny)
## 
## Attaching package: 'shiny'
## 
## The following object is masked _by_ '.GlobalEnv':
## 
##     tags
library(bslib)
## 
## Attaching package: 'bslib'
## 
## The following object is masked from 'package:utils':
## 
##     page
library(dplyr)
>>>>>>> ad0bc60fadc363530d65adc66a558bb30ba913a4

knitr::opts_chunk$set(echo = TRUE)
books = read_csv("./Data/books_with_tags.csv")
## Rows: 9300 Columns: 20
<<<<<<< HEAD
## ── Column specification ──────────────────────────────────────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (9): isbn, authors, title, image_url, top_1, top_2, top_3, top_4, top_5
## dbl (11): book_id, goodreads_book_id, average_rating, ratings_count, work_ratings_count, work_text_reviews_cou...
=======
## ── Column specification ──────────────────────────────
## Delimiter: ","
## chr  (9): isbn, authors, title, image_url, top_1, top_2, top_3, top_4, top_5
## dbl (11): book_id, goodreads_book_id, average_rating, ratings_count, work_ra...
>>>>>>> ad0bc60fadc363530d65adc66a558bb30ba913a4
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
books_clean = books |> 
  select(-isbn,-ratings_count,-work_ratings_count,-work_text_reviews_count)

books_rate <- books_clean |>
  mutate(average_rating = round(average_rating*2)/2)
authors <- unique(books_rate$authors)

ui <- fluidPage(
<<<<<<< HEAD

=======
  
>>>>>>> ad0bc60fadc363530d65adc66a558bb30ba913a4
  selectInput("search_by", 
              label = "Search by:", 
              choices = c("Select", "Author", "Genre")),

  conditionalPanel(
    condition = "input.search_by == 'Author'",
    selectizeInput("authors", 
                   label = "Start typing an author's name:", 
                   choices = authors, 
                   options = list(
                     placeholder = 'Select an author...',
                     create = FALSE, 
                     maxItems = 1,
                     highlight = TRUE))
  ),

  conditionalPanel(
    condition = "input.search_by == 'Genre'",
    selectInput("search_genre", 
                label = "Choose Genre(s):", 
                choices = unique(c(books_rate$top_1, books_rate$top_2, books_rate$top_3, books_rate$top_4, books_rate$top_5)), 
                multiple = TRUE)  
  ),
  
  conditionalPanel( 
    condition = "input.search_by == 'Genre' || input.search_by == 'Author'",
    selectInput("average_rating", 
                label = "Choose Rating:", 
                choices = unique(books_rate$average_rating), 
                selected = NULL)
  ),
  
  actionButton("recommend", "Get Recommendations"),
  
  h3("Your Recommended Books:"),
  uiOutput("book_list")
)
<<<<<<< HEAD
## Warning: The select input "authors" contains a large number of options; consider using server-side selectize for
## massively improved performance. See the Details section of the ?selectizeInput help topic.
## Warning: The select input "search_genre" contains a large number of options; consider using server-side selectize
## for massively improved performance. See the Details section of the ?selectizeInput help topic.
=======
## Warning: The select input "authors" contains a large number of options;
## consider using server-side selectize for massively improved performance. See
## the Details section of the ?selectizeInput help topic.
## Warning: The select input "search_genre" contains a large number of options;
## consider using server-side selectize for massively improved performance. See
## the Details section of the ?selectizeInput help topic.
>>>>>>> ad0bc60fadc363530d65adc66a558bb30ba913a4
server <- function(input, output, session) {
  
  filtered_books <- reactive({
    booktok <- books_rate
    
    if (length(input$search_genre) > 0) {
      booktok <- booktok %>%
        filter(
          top_1 %in% input$search_genre | 
          top_2 %in% input$search_genre | 
          top_3 %in% input$search_genre | 
          top_4 %in% input$search_genre | 
          top_5 %in% input$search_genre
        )
    }
    
    if (input$search_by == "Author" && input$authors != "") {
      booktok <- booktok %>% filter(authors == input$authors)
    }
    
    
    if (!is.null(input$average_rating) && input$average_rating != "") {
      booktok <- booktok %>% filter(average_rating == as.numeric(input$average_rating))
    }
    
    booktok %>% distinct(title, .keep_all = TRUE)
  })
  
  observeEvent(input$recommend, {
    output$book_list <- renderUI({
      booktok <- filtered_books()
       
      if (nrow(booktok) < 5 && !is.null(input$average_rating)) { 
        selected_rating <- as.numeric(input$average_rating)
        
        lower_rating_books <- books_rate %>% 
          filter(average_rating == (selected_rating - 1)) %>% 
          distinct(title, .keep_all = TRUE)
        
        # Only bind rows if there are books with lower rating
        if (nrow(lower_rating_books) > 0) {
          booktok <- bind_rows(booktok, lower_rating_books)
        }
      }
      
      books_to_show <- head(booktok, 5)
      
        if (nrow(books_to_show) > 0) {
        tagList(
          lapply(1:nrow(books_to_show), function(i) {
            lower_rated <- books_to_show$average_rating[i] < as.numeric(input$average_rating)
            
            div(
              img(src = books_to_show$image_url[i], width = "250px", height = "300px"),  
              strong(books_to_show$title[i]), 
              if (lower_rated) {
                span(style = "color: brown; font-weight: bold;", "(Rated Below Your Selection)")
              },
              p(paste("Rating:", books_to_show$average_rating[i]))
            )
          })
        )
      } else {
        p("No books found based on your selection.")
      }
    })
  })
}

shinyApp(ui = ui, server = server)
<<<<<<< HEAD ======= >>>>>>> ad0bc60fadc363530d65adc66a558bb30ba913a4